/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package datenbank;

import java.sql.*;
import java.util.*;
import data.*;
import java.util.Date;
import java.rmi.RemoteException;
import java.text.*;

/**
 *
 * @author Daniel
 */
public class ZuordnungMapper {

    private static ZuordnungMapper zuordnungMapper = null;

    /*
     * statische Methode, die sicherstellt, dass nur eine Istanz von zuordnungMapper erzeugt wird.
     *
     * @return Das zuordnungMapper -Objekt.
     */
    public static ZuordnungMapper zuordnungMapper() {
        if (zuordnungMapper == null) {
            zuordnungMapper = new ZuordnungMapper();
        }

        return zuordnungMapper;
    }

    /**
     * Bei dieser Methode geht es um das hinzufügen eines Produkts (produktElement)
     * zu einer Bestellung (bestellElement) in der Datenbank.
     * Diesem bestellElement - Objekt wird ein Produkt neu zugeordnet.
     * @param bestellElement ist das Objekt des Typs Bestellung, dem ein Objekt produktElement des Typs Produkt zugeordnet wird.
     * @param produktElement ist das Objekt des Typs Produkt, das einem anderen Objekt des Typs Bestellung zugeordnet wird.
     */
    public void addZuordnung(Bestellung be, Produkt pe, int anzahl) throws RemoteException {
        /** Stellt durch Aufruf der connection() Methode der DBConnection-Klasse, die Verbindung zur Datenbank her. */
        Connection con = DBConnection.connection();

        try {
            // Leeres SQL-Statement stmt wird angelegt.
            Statement stmt = con.createStatement();
            //Statement wird ausgefüllt und als Query an die DB geschickt.
            stmt.executeUpdate("INSERT INTO Bestell_Produkt (bestell_id,produkt_id,anzahl)" +
                    "VALUES (" +
                    be.get_bestell_id() + "," +
                    pe.get_produkt_id() + "," +
                    anzahl + ")");

        } catch (SQLException e2) {
            e2.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * Bei dieser Methode geht es um das Ändern einer Zuordnung in der Datenbank.
     * Dabei kann die Anzahl der Produkte in einer Bestellung geändert werden.
     * @param bestellElement ist das Objekt vom Typ Bestellung, bei dem die Anzahl des zugeordneten Produkte geändert werden soll.
     * @param produktElement beschreibt das Objekt vom Typ Produkte, bei welchem die Anzahl der Zuordnung zum Objekt Bestellnung geändert werden soll.
     */
    public void updateZuordnung(Bestellung be, Produkt pe, int anzahl) throws RemoteException {
        /** Stellt durch Aufruf der connection() Methode der DBConnection-Klasse, die Verbindung zur Datenbank her. */
        Connection con = DBConnection.connection();

        try {
            // Leeres SQL-Statement stmt wird angelegt.
            Statement stmt = con.createStatement();
            //Statement wird ausgefüllt und als Query an die DB geschickt.
            stmt.executeUpdate("UPDATE Bestell_Produkt " +
                    "SET anzahl= " + anzahl + " " +
                    "WHERE bestell_id= " + be.get_bestell_id() + " " +
                    "AND produkt_id= " +pe.get_produkt_id());

        } catch (SQLException e2) {
            e2.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Bei dieser Methode geht es um das löschen der Zuordnung eines Elements/Bauteils(quellElement)
     * zu einem Bauteil (zielElement) in der Datenbank.
     * Dabei wird nur die Verbindung, die ein Bauteil zuordnet aus der Datenbanktabelle gelöscht.
     * @param quellElement beschreibt das Objekt vom Typ Element, das eine Zuordnung zu zielElement besizt, d.h. in dem objekt verbaut ist
     * @param zielElement beschreibt das Objekt vom Typ Bauteil, in dem das Objekt quellElement vom Typ Element verbaut ist

     */
    public void deleteZuordnung(Bestellung be, Produkt pe) throws RemoteException {
        /** Stellt durch Aufruf der connection() Methode der DBConnection-Klasse, die Verbindung zur Datenbank her. */
        Connection con = DBConnection.connection();

        try {
            // Leeres SQL-Statement stmt wird angelegt.
            Statement stmt = con.createStatement();

            //Statement wird ausgefüllt und als Query an die DB geschickt.
            stmt.executeUpdate("DELETE FROM Bestell_Produkt " +
                    "WHERE bestell_id=" + be.get_bestell_id() + " " +
                    "AND produkt_id=" + pe.get_produkt_id());

        } catch (SQLException e2) {
            e2.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Bei dieser Methode wird eine Bestellung übergeben und dadurch werden alle Datensätze aus der Datenbank gelöscht
     * zu der die Bestellung gehört.
     * @param Bestellung be, die Bestellung die gelöscht werden soll und dementsprechend alle Zeilen mit der bestell_id
     */
    public void deleteByBestellID(Bestellung be) throws RemoteException {
        /** Stellt durch Aufruf der connection() Methode der DBConnection-Klasse, die Verbindung zur Datenbank her. */
        Connection con = DBConnection.connection();

        try {
            // Leeres SQL-Statement stmt wird angelegt.
            Statement stmt = con.createStatement();

            //Statement wird ausgefüllt und als Query an die DB geschickt.
            stmt.executeUpdate("DELETE FROM Bestell_Produkt " +
                    "WHERE bestell_id=" + be.get_bestell_id());

        } catch (SQLException e2) {
            e2.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Diese Methode überprüft ob ein Produkt-Objekt pr existiert, d.h. ob es irgenwo in der Tabelle in der Datenbank steht
     * @param pr ist das Primärschlüsselattribut, nachdem in der Tabelle gesucht werden soll.
     * @return Wenn das Produkt existiert wird der Wert true vom Typ boolean zurückgegeben.
     * wenn das Bauteil nicht existiert wird der Wert false vom Typ boolean zurückgegeben.
     *
    */
    public boolean existsZuordnung(Produkt pr) throws RemoteException {
        /** Stellt durch Aufruf der connection() Methode der DBConnection-Klasse, die Verbindung zur Datenbank her. */

        Connection con = DBConnection.connection();
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {

                        stmt = con.prepareStatement(
                        "SELECT * FROM Bestell_Produkt WHERE produkt_id =" + pr.get_produkt_id() );
                         rs= stmt.executeQuery();
                         if (rs.next()==true) {
                             return true;
                          }

                         else {
                             return false;
                          }

                } catch (SQLException e) {
                        e.printStackTrace();
                        return false;
                }

    }


        /**
     * Bei dieser Methode geht es um das hinzufügen eines Produkts (produktElement)
     * zu einer Bestellung (bestellElement) in der Datenbank.
     * Diesem bestellElement - Objekt wird ein Produkt neu zugeordnet.
     * @param bestellElement ist das Objekt des Typs Bestellung, dem ein Objekt produktElement des Typs Produkt zugeordnet wird.
     * @param produktElement ist das Objekt des Typs Produkt, das einem anderen Objekt des Typs Bestellung zugeordnet wird.
     */
    public int getPRAnzahl_byTime(Timestamp start, Timestamp end, Produkt pr) throws RemoteException {
        /** Stellt durch Aufruf der connection() Methode der DBConnection-Klasse, die Verbindung zur Datenbank her. */
        Connection con = DBConnection.connection();
        int anzahl = 0;
        try {
            Statement stmt = con.createStatement();

           // Umwandlung des Timestamps start in das Format was die Datenbank benötigt um die Abfrage durchzuführen
            String startstring = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(start);

            // Variable zum Produkte zählen


            // Umwandlung des Timestamps end in das Format was die Datenbank benötigt um die Abfrage durchzuführen
            String endstring = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(end);

            ResultSet rs = stmt.executeQuery(
                    "SELECT anzahl " +
                    "FROM Bestell_Produkt " +
                    "WHERE datum BETWEEN '" +
                    startstring + "' AND '" + endstring + "' AND produkt_id=" + pr.get_produkt_id());


            // Für jeden Eintrag im Suchergebnis wird nun ein Bestell-Objekt be erstellt.
            while (rs.next()) {
                try {
                    // Hier die Anzahl der Produkte gezählt
                    anzahl = anzahl + rs.getInt("anzahl");


                } catch (Exception e) {
                    e.printStackTrace();
                    //Bei einer evtl. Exception wird die while-Schleife abgebrochen.
                    break;
                }
            }
            // Anzahl wird zurückgegeben.

        } catch (SQLException e2) {
            e2.printStackTrace();


        }
        return anzahl;
    }
}
